﻿// --------------------------------
// <copyright file="Perspective.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Lukáš Molnár</author>

// <email>molnaluk@fit.cvut.cz</email>

// <date>27. 11. 2011 12:20:26</date>

// <summary>
//
// </summary>
// --------------------------------
#if WINDOWS

using System.ComponentModel;

#endif

using Microsoft.Xna.Framework;

namespace FITClub.Util
{
    public class Camera
    {
#if WINDOWS
        [Category("Camera Look At")]
#endif
        public Vector3 Position;

#if WINDOWS
        [Category("Camera Look At")]
#endif
        public Vector3 Up;

#if WINDOWS
        [Category("Camera Look At")]
#endif
        public Vector3 Target;

        public Camera()
        {
            this.Default();
        }

        public void Default()
        {
            this.Position = new Vector3(0, 1, 6);
            this.Target = Vector3.Zero;
            this.Up = Vector3.Up;
        }

        public Matrix CameraLookAt()
        {
            return Matrix.CreateLookAt(this.Position, this.Target, this.Up);
        }
    }

    public class Perspective
    {
        public float AspectRatio { get; set; }

        public float FieldOfView { get; set; }

        public float NearPlaneDistance { get; set; }

        public float FarPlaneDistance { get; set; }

        public static Perspective Default(GraphicsDeviceManager graphics)
        {
            return new Perspective()
            {
                AspectRatio = (float)graphics.PreferredBackBufferWidth / (float)graphics.PreferredBackBufferHeight,
                FieldOfView = MathHelper.PiOver4,
                FarPlaneDistance = 1000,
                NearPlaneDistance = 0.1f
            };
        }

        public Matrix PerspectiveFiledOfView()
        {
            return Matrix.CreatePerspectiveFieldOfView(
                 this.FieldOfView,
                 this.AspectRatio,
                 this.NearPlaneDistance,
                 this.FarPlaneDistance
             );
        }

        public override string ToString()
        {
            return string.Format("FiledOfView={0} AspectRatio={1} NearPlaneDistance={2} FarPlaneDistance={3}",
                this.AspectRatio, this.FieldOfView, this.NearPlaneDistance, this.FarPlaneDistance);
        }
    }

    public class CameraAndPerspective
    {
        public CameraAndPerspective()
        {
            this.CameraConfig = new Camera();
            this.PerspectiveConfig = new Perspective() { AspectRatio = 5f / 3f, FarPlaneDistance = 1000f, NearPlaneDistance = 0.1f, FieldOfView = MathHelper.PiOver4 };
        }

#if WINDOWS

        [Category("Perspective Filed Of View")]
        [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
        public Perspective PerspectiveConfig { get; set; }

#if WINDOWS

        [Category("Camera Look At")]
        [TypeConverter(typeof(ExpandableObjectConverter))]
#endif
        public Camera CameraConfig { get; set; }
    }
}